import { reactive, toRefs, computed, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import http from '../utils/http'
import download from 'jax/utils/download'

export function usePageList(options = {}) {
  const route = useRoute()
  const router = useRouter()

  options = {
    useRouteQuery: true,
    type: 'page',
    ...options,
  }

  const { useRouteQuery, type, page, pageSize, api, key, defaultDetail } = options

  const query = {
    ...(useRouteQuery && type == 'page' ? { ...route.query } : {}),
    ...options.query,
  }

  const state = reactive({
    breadcrumb: route.meta.breadcrumb || [], // 面包屑

    total: 0, // 总条数
    page: page || route.query.page || 1, // 当前页数
    pageSize: pageSize || route.query.pageSize || 20, // 每页条数

    selectData: [], // 所选数据
    loading: false, // 加载中

    key: key || route.meta.key || 'id', // 主键

    data: [], // 列表数据

    api: api || route.meta.api, // Api

    query: { ...query }, // 查询参数（解构处理，避免搜索指向同一个）

    detail: {},

    defaultDetail, // 默认详情数据

    shwoEdit: false,
  })

  const actions = {
    /**
     * 初始化
     */
    initData(options = {}) {
      actions.getData()
    },

    /**
     * 刷新
     */
    refresh() {
      actions.getData()
    },

    /**
     * 获取数据
     */
    async getData(config = {}) {
      state.loading = true

      // 后台使用
      http({
        url: state.api,
        params: {
          page: state.page,
          pageSize: state.pageSize,
          ...state.query,
        },
        ...config,
      })
        .then(async res => {
          state.data = res.list
          state.total = res.total
          state.page = res.page
          state.pageSize = res.pageSize

          if (actions.afterGetData) await actions.afterGetData()
        })
        .finally(() => {
          state.loading = false
        })
    },

    // 删除
    handleDelete(item) {
      ElMessageBox.confirm('确认删除?', '提示', {
        type: 'warning',
      }).then(() => {
        const id = item[state.key]
        http.delete(`${state.api}/${id}`).then(res => {
          ElMessage.success('删除成功')
          actions.refresh()
        })
      })
    },

    /**
     * 修改操作
     * @param {Object} item 修改的行数据
     * @param {Object} newItem 修改字段组成的对象
     * @param {String} confirmMsg 确认提示语
     * @param {String} successMsg 请求完成提示语
     */
    async handleUpdate(item, newItem, confirmMsg, successMsg) {
      if (confirmMsg) {
        await ElMessageBox.confirm(confirmMsg, '提示', {
          type: 'warning',
        })
      }

      http.put(`${state.api}/${item[state.key]}`, newItem).then(res => {
        ElMessage.success(successMsg || '操作成功')
        actions.refresh()
      })
    },

    /**
     * 当选择项发生变化时会触发该事件
     * @param {Array}  selection
     */
    handleSelectionChange(val) {
      state.selectData = val
    },

    // 批量删除
    handleBatchDelete(successMsg) {
      const idList = state.selectData.map(item => item[this.key])
      if (!idList || !idList.length) returnElMessage.warning('请先选择数据')

      ElMessageBox.confirm('确认批量删除?', '警告', {
        type: 'warning',
      }).then(res => {
        http.delete(`${state.api}/${idList.join(',')}`).then(res => {
          ElMessage.success(successMsg || '删除成功')
          actions.refresh()
        })
      })
    },

    // 批量修改
    handleBatchUpdate(newData, confirm, successMsg) {
      const idList = state.selectData.map(item => item[this.key])
      if (!idList || !idList.length) returnElMessage.warning('请先选择数据')

      ElMessageBox.confirm(confirm || '确认操作?', '警告', {
        type: 'warning',
      }).then(res => {
        http.put(`${state.api}/${idList.join(',')}`, newData).then(res => {
          ElMessage.success(successMsg || '操作成功')
          actions.refresh()
        })
      })
    },

    /**
     * 搜索
     */
    handleSearch() {
      state.page = 1
      state.total = 0
      actions.setUrlQuery()
      actions.refresh()
    },

    /**
     * 重置
     */
    handleReset(isSearch = true) {
      state.query = { ...options.query }

      actions.setUrlQuery()

      if (isSearch) actions.refresh()
    },

    /**
     * 设置URL
     */
    setUrlQuery() {
      const query = {
        ...state.query,
        page: state.page,
        pageSize: state.pageSize,
      }

      state.query = query

      if (type == 'page') {
        router.replace({
          path: route.path,
          query,
        })
      }
    },

    // 分页切换
    handlePageChange(page) {
      state.page = page

      actions.setUrlQuery()
      actions.refresh()
    },

    // 条数切换
    handleSizeChange(pageSize) {
      state.page = 1
      state.pageSize = pageSize

      actions.setUrlQuery()
      actions.refresh()
    },

    // mehtods
    // 新增
    handleAdd(item) {
      state.shwoEdit = true
      state.detail = {
        ...state.defaultDetail,
        ...item,
      }

      actions.afterHandleEdit && actions.afterHandleEdit()
    },

    handleEdit(item) {
      state.shwoEdit = true
      state.detail = {
        ...state.defaultDetail,
        ...item,
      }

      actions.afterHandleEdit && actions.afterHandleEdit()
    },

    /**
     * 导出
     * @param {*} type 导出类型 0、导出当页 1、导出所有
     */
    handleExport(isAll = true) {
      http
        .get(state.api, {
          params: {
            ...state.query,
            isExport: 1,
            pageSize: isAll === true ? -1 : state.pageSize,
          },
          responseType: 'blob',
          showLoading: '导出中...',
        })
        .then(res => {
          const content = res.data // 返回的内容
          const fileName = res.headers['content-disposition'].split('filename="').pop().replace('"', '') // 下载文件名
          download(content, fileName)
        })
    },

    /**
     * 提交
     * @param {Boolean} goBack
     */
    handleSubmit(goBack = true) {
      let detail = {
        ...state.detail,
      }

      const id = detail[state.key]

      // 提交成功后
      const onSuccess = res => {
        ElMessage.success(state.detail.id ? '保存成功' : '添加成功')
        if (goBack) state.shwoEdit = false
        actions.refresh()
      }

      if (actions.handleBeforeSubmit) {
        let newData = actions.handleBeforeSubmit(detail)
        if (newData) detail = newData
        else if (newData == false) return
      }

      if (id) {
        return http
          .put(`${state.api}/${id}`, detail, {
            showLoading: true,
          })
          .then(onSuccess)
      } else {
        return http
          .post(`${state.api}`, detail, {
            showLoading: true,
          })
          .then(onSuccess)
      }
    },
  }

  /**
   * @description: element 中的 formatter 属性，对 el-table 中 Table-column 的数据为空时进行格式化
   * @param {*} row 当前的行的数据对象
   * @param {*} column 当前列的相关信息
   * @param {*} cellValue 当前属性的值
   * @return {*} 如果有值时，显示值，没有值，或者值为空时，显示 -
   */
  const onFormatter = (row, column, cellValue) => {
    return cellValue ? cellValue : '/'
  }

  if (type == 'page') onMounted(() => actions.initData())

  state.selectd = computed(() => state.selectData && state.selectData.length)

  return {
    ...toRefs(state),
    ...actions,
    pageData: state,
    pageActions: actions,
    onFormatter,
  }
}
